{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 8.11 \u7b80\u5316\u6570\u636e\u7ed3\u6784\u7684\u521d\u59cb\u5316\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### \u95ee\u9898\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\u4f60\u5199\u4e86\u5f88\u591a\u4ec5\u4ec5\u7528\u4f5c\u6570\u636e\u7ed3\u6784\u7684\u7c7b\uff0c\u4e0d\u60f3\u5199\u592a\u591a\u70e6\u4eba\u7684 __init__() \u51fd\u6570"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### \u89e3\u51b3\u65b9\u6848\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\u53ef\u4ee5\u5728\u4e00\u4e2a\u57fa\u7c7b\u4e2d\u5199\u4e00\u4e2a\u516c\u7528\u7684 __init__() \u51fd\u6570\uff1a"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "import math\n\nclass Structure1:\n    # Class variable that specifies expected fields\n    _fields = []\n\n    def __init__(self, *args):\n        if len(args) != len(self._fields):\n            raise TypeError('Expected {} arguments'.format(len(self._fields)))\n        # Set the arguments\n        for name, value in zip(self._fields, args):\n            setattr(self, name, value)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\u7136\u540e\u4f7f\u4f60\u7684\u7c7b\u7ee7\u627f\u81ea\u8fd9\u4e2a\u57fa\u7c7b:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# Example class definitions\nclass Stock(Structure1):\n    _fields = ['name', 'shares', 'price']\n\nclass Point(Structure1):\n    _fields = ['x', 'y']\n\nclass Circle(Structure1):\n    _fields = ['radius']\n\n    def area(self):\n        return math.pi * self.radius ** 2"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\u4f7f\u7528\u8fd9\u4e9b\u7c7b\u7684\u793a\u4f8b\uff1a"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "s = Stock('ACME', 50, 91.1)\np = Point(2, 3)\nc = Circle(4.5)\ns2 = Stock('ACME', 50)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\u5982\u679c\u8fd8\u60f3\u652f\u6301\u5173\u952e\u5b57\u53c2\u6570\uff0c\u53ef\u4ee5\u5c06\u5173\u952e\u5b57\u53c2\u6570\u8bbe\u7f6e\u4e3a\u5b9e\u4f8b\u5c5e\u6027\uff1a"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "class Structure2:\n    _fields = []\n\n    def __init__(self, *args, **kwargs):\n        if len(args) > len(self._fields):\n            raise TypeError('Expected {} arguments'.format(len(self._fields)))\n\n        # Set all of the positional arguments\n        for name, value in zip(self._fields, args):\n            setattr(self, name, value)\n\n        # Set the remaining keyword arguments\n        for name in self._fields[len(args):]:\n            setattr(self, name, kwargs.pop(name))\n\n        # Check for any remaining unknown arguments\n        if kwargs:\n            raise TypeError('Invalid argument(s): {}'.format(','.join(kwargs)))\n# Example use\nif __name__ == '__main__':\n    class Stock(Structure2):\n        _fields = ['name', 'shares', 'price']\n\n    s1 = Stock('ACME', 50, 91.1)\n    s2 = Stock('ACME', 50, price=91.1)\n    s3 = Stock('ACME', shares=50, price=91.1)\n    # s3 = Stock('ACME', shares=50, price=91.1, aa=1)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\u4f60\u8fd8\u80fd\u5c06\u4e0d\u5728 _fields \u4e2d\u7684\u540d\u79f0\u52a0\u5165\u5230\u5c5e\u6027\u4e2d\u53bb\uff1a"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "class Structure3:\n    # Class variable that specifies expected fields\n    _fields = []\n\n    def __init__(self, *args, **kwargs):\n        if len(args) != len(self._fields):\n            raise TypeError('Expected {} arguments'.format(len(self._fields)))\n\n        # Set the arguments\n        for name, value in zip(self._fields, args):\n            setattr(self, name, value)\n\n        # Set the additional arguments (if any)\n        extra_args = kwargs.keys() - self._fields\n        for name in extra_args:\n            setattr(self, name, kwargs.pop(name))\n\n        if kwargs:\n            raise TypeError('Duplicate values for {}'.format(','.join(kwargs)))\n\n# Example use\nif __name__ == '__main__':\n    class Stock(Structure3):\n        _fields = ['name', 'shares', 'price']\n\n    s1 = Stock('ACME', 50, 91.1)\n    s2 = Stock('ACME', 50, 91.1, date='8/2/2012')"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### \u8ba8\u8bba\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\u5f53\u4f60\u9700\u8981\u4f7f\u7528\u5927\u91cf\u5f88\u5c0f\u7684\u6570\u636e\u7ed3\u6784\u7c7b\u7684\u65f6\u5019\uff0c\n\u76f8\u6bd4\u624b\u5de5\u4e00\u4e2a\u4e2a\u5b9a\u4e49 __init__() \u65b9\u6cd5\u800c\u5df2\uff0c\u4f7f\u7528\u8fd9\u79cd\u65b9\u5f0f\u53ef\u4ee5\u5927\u5927\u7b80\u5316\u4ee3\u7801\u3002"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\u5728\u4e0a\u9762\u7684\u5b9e\u73b0\u4e2d\u6211\u4eec\u4f7f\u7528\u4e86 setattr() \u51fd\u6570\u7c7b\u8bbe\u7f6e\u5c5e\u6027\u503c\uff0c\n\u4f60\u53ef\u80fd\u4e0d\u60f3\u7528\u8fd9\u79cd\u65b9\u5f0f\uff0c\u800c\u662f\u60f3\u76f4\u63a5\u66f4\u65b0\u5b9e\u4f8b\u5b57\u5178\uff0c\u5c31\u50cf\u4e0b\u9762\u8fd9\u6837\uff1a"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "class Structure:\n    # Class variable that specifies expected fields\n    _fields= []\n    def __init__(self, *args):\n        if len(args) != len(self._fields):\n            raise TypeError('Expected {} arguments'.format(len(self._fields)))\n\n        # Set the arguments (alternate)\n        self.__dict__.update(zip(self._fields,args))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\u5c3d\u7ba1\u8fd9\u4e5f\u53ef\u4ee5\u6b63\u5e38\u5de5\u4f5c\uff0c\u4f46\u662f\u5f53\u5b9a\u4e49\u5b50\u7c7b\u7684\u65f6\u5019\u95ee\u9898\u5c31\u6765\u4e86\u3002\n\u5f53\u4e00\u4e2a\u5b50\u7c7b\u5b9a\u4e49\u4e86 __slots__ \u6216\u8005\u901a\u8fc7property(\u6216\u63cf\u8ff0\u5668)\u6765\u5305\u88c5\u67d0\u4e2a\u5c5e\u6027\uff0c\n\u90a3\u4e48\u76f4\u63a5\u8bbf\u95ee\u5b9e\u4f8b\u5b57\u5178\u5c31\u4e0d\u8d77\u4f5c\u7528\u4e86\u3002\u6211\u4eec\u4e0a\u9762\u4f7f\u7528 setattr() \u4f1a\u663e\u5f97\u66f4\u901a\u7528\u4e9b\uff0c\u56e0\u4e3a\u5b83\u4e5f\u9002\u7528\u4e8e\u5b50\u7c7b\u60c5\u51b5\u3002"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\u8fd9\u79cd\u65b9\u6cd5\u552f\u4e00\u4e0d\u597d\u7684\u5730\u65b9\u5c31\u662f\u5bf9\u67d0\u4e9bIDE\u800c\u8a00\uff0c\u5728\u663e\u793a\u5e2e\u52a9\u51fd\u6570\u65f6\u53ef\u80fd\u4e0d\u592a\u53cb\u597d\u3002\u6bd4\u5982\uff1a"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "help(Stock)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\u53ef\u4ee5\u53c2\u80039.16\u5c0f\u8282\u6765\u5f3a\u5236\u5728 __init__() \u65b9\u6cd5\u4e2d\u6307\u5b9a\u53c2\u6570\u7684\u7c7b\u578b\u7b7e\u540d\u3002"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.7.1"
    },
    "toc": {
      "base_numbering": 1,
      "nav_menu": {},
      "number_sections": true,
      "sideBar": true,
      "skip_h1_title": true,
      "title_cell": "Table of Contents",
      "title_sidebar": "Contents",
      "toc_cell": false,
      "toc_position": {},
      "toc_section_display": true,
      "toc_window_display": true
    }
  },
  "nbformat": 4,
  "nbformat_minor": 2
}